import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '../services/http_service.dart';
import '../services/gitcode_api_service.dart';

/// 仓库列表页面
class RepositoryListPage extends StatefulWidget {
  final GitCodeApiService apiService;
  final HttpService httpService;
  
  const RepositoryListPage({
    super.key,
    required this.apiService,
    required this.httpService,
  });
  
  @override
  State<RepositoryListPage> createState() => _RepositoryListPageState();
}

class _RepositoryListPageState extends State<RepositoryListPage> {
  List<dynamic> _repositories = [];
  bool _isLoading = false;
  String? _errorMessage;
  int _currentPage = 1;
  final int _perPage = 20;
  bool _hasMore = true;
  CancelToken? _cancelToken;
  final ScrollController _scrollController = ScrollController();
  
  @override
  void initState() {
    super.initState();
    _loadRepositories();
    _scrollController.addListener(_onScroll);
  }
  
  @override
  void dispose() {
    _scrollController.dispose();
    _cancelToken?.cancel('页面销毁');
    super.dispose();
  }
  
  void _onScroll() {
    if (_scrollController.position.pixels >=
            _scrollController.position.maxScrollExtent * 0.8 &&
        !_isLoading &&
        _hasMore) {
      _loadMoreRepositories();
    }
  }
  
  /// 加载仓库列表
  Future<void> _loadRepositories({bool refresh = false}) async {
    if (refresh) {
      setState(() {
        _currentPage = 1;
        _repositories = [];
        _hasMore = true;
      });
    }
    
    final token = widget.httpService.accessToken;
    if (token == null || token.isEmpty) {
      setState(() {
        _errorMessage = '请先配置 Personal Access Token';
        _isLoading = false;
      });
      return;
    }
    
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });
    
    _cancelToken?.cancel('新请求');
    _cancelToken = CancelToken();
    
    try {
      final repos = await widget.apiService.getUserRepositories(
        page: _currentPage,
        perPage: _perPage,
        cancelToken: _cancelToken,
      );
      
      setState(() {
        if (refresh) {
          _repositories = repos;
        } else {
          _repositories.addAll(repos);
        }
        _hasMore = repos.length == _perPage;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _isLoading = false;
        if (e is HttpException) {
          if (e.statusCode == 401) {
            _errorMessage = 'Token 无效，请检查设置';
          } else {
            _errorMessage = '错误: ${e.message}';
          }
        } else {
          _errorMessage = '加载失败: $e';
        }
      });
    }
  }
  
  /// 加载更多仓库
  Future<void> _loadMoreRepositories() async {
    if (!_hasMore || _isLoading) return;
    
    setState(() {
      _currentPage++;
    });
    
    await _loadRepositories();
  }
  
  @override
  Widget build(BuildContext context) {
    if (_repositories.isEmpty && _isLoading) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
    
    if (_errorMessage != null && _repositories.isEmpty) {
      return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(
              Icons.error_outline,
              size: 64,
              color: Colors.red,
            ),
            const SizedBox(height: 16),
            Text(
              _errorMessage!,
              style: const TextStyle(fontSize: 16, color: Colors.red),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: () => _loadRepositories(refresh: true),
              icon: const Icon(Icons.refresh),
              label: const Text('重试'),
            ),
          ],
        ),
      );
    }
    
    return RefreshIndicator(
      onRefresh: () => _loadRepositories(refresh: true),
      child: ListView.builder(
        controller: _scrollController,
        padding: const EdgeInsets.all(8.0),
        itemCount: _repositories.length + (_hasMore ? 1 : 0),
        itemBuilder: (context, index) {
          if (index == _repositories.length) {
            return const Center(
              child: Padding(
                padding: EdgeInsets.all(16.0),
                child: CircularProgressIndicator(),
              ),
            );
          }
          
          final repo = _repositories[index];
          return _buildRepositoryCard(repo);
        },
      ),
    );
  }
  
  Widget _buildRepositoryCard(Map<String, dynamic> repo) {
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0),
      child: InkWell(
        onTap: () {
          // 可以导航到仓库详情页面
          _showRepositoryDetails(repo);
        },
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  const Icon(Icons.folder, color: Colors.blue, size: 20),
                  const SizedBox(width: 8),
                  Expanded(
                    child: Text(
                      repo['full_name'] ?? repo['name'] ?? '未知',
                      style: const TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                  if (repo['private'] == true)
                    const Icon(Icons.lock, size: 16, color: Colors.orange),
                ],
              ),
              if (repo['description'] != null) ...[
                const SizedBox(height: 8),
                Text(
                  repo['description'],
                  style: TextStyle(
                    fontSize: 14,
                    color: Colors.grey.shade700,
                  ),
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ],
              const SizedBox(height: 12),
              Row(
                children: [
                  if (repo['language'] != null) ...[
                    Icon(Icons.circle, size: 12, color: _getLanguageColor(repo['language'])),
                    const SizedBox(width: 4),
                    Text(
                      repo['language'],
                      style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
                    ),
                    const SizedBox(width: 16),
                  ],
                  if (repo['stargazers_count'] != null) ...[
                    const Icon(Icons.star, size: 14, color: Colors.amber),
                    const SizedBox(width: 4),
                    Text(
                      repo['stargazers_count'].toString(),
                      style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
                    ),
                    const SizedBox(width: 16),
                  ],
                  if (repo['forks_count'] != null) ...[
                    const Icon(Icons.call_split, size: 14, color: Colors.grey),
                    const SizedBox(width: 4),
                    Text(
                      repo['forks_count'].toString(),
                      style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
                    ),
                  ],
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
  
  Color _getLanguageColor(String? language) {
    if (language == null) return Colors.grey;
    final colors = {
      'Dart': Colors.blue,
      'JavaScript': Colors.yellow,
      'TypeScript': Colors.blue,
      'Python': Colors.blue,
      'Java': Colors.orange,
      'Kotlin': Colors.purple,
      'Swift': Colors.orange,
      'Go': Colors.cyan,
      'Rust': Colors.orange,
      'C++': Colors.blue,
      'C': Colors.blue,
    };
    return colors[language] ?? Colors.grey;
  }
  
  void _showRepositoryDetails(Map<String, dynamic> repo) {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (context) => DraggableScrollableSheet(
        initialChildSize: 0.7,
        minChildSize: 0.5,
        maxChildSize: 0.95,
        builder: (context, scrollController) => SingleChildScrollView(
          controller: scrollController,
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Center(
                child: Container(
                  width: 40,
                  height: 4,
                  margin: const EdgeInsets.only(bottom: 16),
                  decoration: BoxDecoration(
                    color: Colors.grey.shade300,
                    borderRadius: BorderRadius.circular(2),
                  ),
                ),
              ),
              Text(
                repo['full_name'] ?? repo['name'] ?? '未知',
                style: const TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              if (repo['description'] != null) ...[
                const SizedBox(height: 8),
                Text(
                  repo['description'],
                  style: TextStyle(color: Colors.grey.shade700),
                ),
              ],
              const SizedBox(height: 16),
              const Divider(),
              _buildDetailRow('URL', repo['html_url']),
              _buildDetailRow('语言', repo['language']),
              _buildDetailRow('Stars', repo['stargazers_count']?.toString()),
              _buildDetailRow('Forks', repo['forks_count']?.toString()),
              _buildDetailRow('Watchers', repo['watchers_count']?.toString()),
              _buildDetailRow('是否公开', repo['private'] == true ? '私有' : '公开'),
              if (repo['created_at'] != null)
                _buildDetailRow('创建时间', _formatDate(repo['created_at'])),
              if (repo['updated_at'] != null)
                _buildDetailRow('更新时间', _formatDate(repo['updated_at'])),
            ],
          ),
        ),
      ),
    );
  }
  
  Widget _buildDetailRow(String label, String? value) {
    if (value == null) return const SizedBox.shrink();
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 100,
            child: Text(
              label,
              style: TextStyle(
                fontWeight: FontWeight.w500,
                color: Colors.grey.shade700,
              ),
            ),
          ),
          Expanded(
            child: Text(value),
          ),
        ],
      ),
    );
  }
  
  String _formatDate(String? dateString) {
    if (dateString == null) return '未知';
    try {
      final date = DateTime.parse(dateString);
      return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
    } catch (e) {
      return dateString;
    }
  }
}

